package com.shop.cloud.filter;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.shop.cloud.StatusCode;
import com.shop.cloud.auth0.jwt.TokenGenerator;
import com.shop.cloud.auth0.jwt.interfaces.Claim;
import com.shop.cloud.model.response.ErrorEntity;
import com.shop.cloud.util.CookieManager;
import com.shop.cloud.util.MagicConstants;
import com.shop.cloud.util.ServletUtil;

public class PermissionAnnotationInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
        	String  uri=request.getServletPath();
			if(uri.startsWith("/v2/api-docs")||uri.startsWith("/swagger-resources")){
				return true;
			}
			System.out.println(ServletUtil.toString(request));
        	HandlerMethod methodHandler = (HandlerMethod) handler;
            String token = request.getHeader(MagicConstants.USER_TOKEN);
            if (StringUtils.isEmpty(token)) {
                token = request.getParameter(MagicConstants.USER_TOKEN);
            }
            if (StringUtils.isEmpty(token)) {
                token = new CookieManager(request, null).getCookie(MagicConstants.USER_TOKEN);
            }
            //登录判断
            IgnoreAuth annotation = methodHandler.getMethodAnnotation(IgnoreAuth.class);
            // 如果有@IgnoreAuth注解，则不验证token
            if (annotation == null && (StringUtils.isEmpty(token))) {
                writeMessage(request, response);
                return false;
            }
            Map<String, Claim> datas = null;
            if (StringUtils.isNotEmpty(token)) {
                try {
                    datas = TokenGenerator.getClaims(token);        //权限资源信息
                } catch (Exception e) {
                    e.printStackTrace();
                    ServletUtil.writeJson(new ErrorEntity(StatusCode.TOKEN_EXPIRED), response);//token过期
                    return false;
                }
                String userId = datas.get(MagicConstants.SESSION_USER_ID).asString();
                if (annotation != null && (StringUtils.isEmpty(userId))) {
                    writeMessage(request, response);
                    return false;
                }
            }
            //有无权限访问链接
            MagicPermission magicPermission = methodHandler.getMethodAnnotation(MagicPermission.class);
            if (null != magicPermission) {
            	List<String> resources = datas.get(MagicConstants.SESSION_USER_PERMISSIONS).asList(String.class);
                if (StringUtils.isEmpty(token)) {
                    writeMessage(request, response);
                    return false;
                }
                // 检查是否有权限访问
                boolean hasPermission = false;
                Iterator<String> iterator = resources.iterator();
                while (iterator.hasNext()) {
                	String resource = iterator.next();
                    if (("/" +resource).equals(uri)) {        //根据请求链接判断
                        hasPermission = true;
                    }
                }
                if (!hasPermission) {
                    writeMessage(request, response);
                    return false;
                }
            }
        }
        return true;
    }

    private void writeMessage(HttpServletRequest request, HttpServletResponse response) throws IOException {
            response.setHeader("sessionstatus", "timeout");
            ServletUtil.writeJson(new ErrorEntity(StatusCode.INVALID_ACCESS), response);
    }

}
